import { Inject, Injectable } from '@nestjs/common';
import { Response } from 'src/common/utils';
import { FuzzyLoacation } from './dto/fuzzyLocation';
import { DrizzalPool } from 'src/libs/drizzle.module';
import {
  lucky_area_store_food,
  lucky_food,
  lucky_food_group,
  lucky_store,
} from 'src/sql_schema/schema';
import { sql, eq, and, isNull, or } from 'drizzle-orm';
import { NearestStroeVo } from './vo/nearstStore';

@Injectable()
export class StoreService {
  constructor(
    @Inject()
    private drizzalPool: DrizzalPool,
  ) {}

  /**
   * 根据用户的坐标位置，获取离他最近的门店
   * @param longitude
   * @param latitude
   * @returns
   */
  async getNearestStoreByLocation(longitude: number, latitude: number) {
    const distanceSql = sql<number>`
        6371000 * ACOS(
          LEAST(1, GREATEST(-1, 
              SIN(RADIANS(${latitude})) * SIN(RADIANS(${lucky_store.latitude})) 
            + COS(RADIANS(${latitude})) * COS(RADIANS(${lucky_store.latitude})) 
            * COS(RADIANS(${lucky_store.longitude}) - RADIANS(${longitude}))
            ))
          )`;
    const results = await this.drizzalPool
      .getDataSource()
      .select({
        id: lucky_store.id,
        name: lucky_store.name,
        distance: distanceSql,
      })
      .from(lucky_store)
      .orderBy(distanceSql)
      .limit(1);

    const store = new NearestStroeVo();
    store.id = String(results[0].id);
    store.name = results[0].name;
    store.distance = results[0].distance.toFixed(2);
    return Response.success().setData(store);
  }

  /**
   * 根据门店id获取门店的菜单
   * 多数情况门店的菜单是统一
   * todo:但是个别情况下门店的菜单可能根据地域有一些区域性的尝试，这部分的逻辑在管理端，进行实验
   * @param id
   * @returns
   */
  async getFoodList(id: string) {
    const results = await this.drizzalPool
      .getDataSource()
      .select()
      .from(lucky_food)
      .leftJoin(lucky_food_group, eq(lucky_food.groupId, lucky_food_group.id))
      .leftJoin(
        lucky_area_store_food,
        eq(lucky_food.id, lucky_area_store_food.food_id),
      )
      .where(
        and(
          eq(lucky_food.active, 1),
          or(
            isNull(lucky_area_store_food.store_id),
            eq(lucky_area_store_food.store_id, Number(id)),
          ),
        ),
      );
    const voList = results.map((item) => {
      const newItem: any = Object.assign({}, item.lucky_food);
      newItem.group_name = item.lucky_food_group?.name;
      newItem.group_pid = item.lucky_food_group?.pid;
      newItem.group_decription = item.lucky_food_group?.description;
      return newItem;
    });
    return Response.success().setData(voList);
  }

  getStoreList(query: FuzzyLoacation) {
    return Response.success().setData(query);
  }
}
